import os
import struct
import Utils.Utils

def make_palette_red_first(pal):
    #a,r,g,b -> r,g,b
    red_pal = BSAPalette()
    red_pal.set_palette([(r,g,b) for (a,r,g,b) in pal])
    return red_pal

def make_palette_blue_first(pal):
    #a,r,g,b -> b,g,r
    #TODO: check if this is okay
    blue_pal = BSAPalette()
    blue_pal.set_palette([(b,g,r) for (a,r,g,b) in pal])
    return blue_pal

def make_palette_argb(pal):
    return pal

class BSAPalette:
    ENTRY_NUMBER = 3
    PALETTE_SIZE = 256
    
    def __init__(self, filename = ''):
        self._filename = filename
        self._palette = [0 for i in xrange(self.PALETTE_SIZE)]
        
    def __repr__(self):
        return "BSAPalette: [filename=" + self._filename +\
            "|palette=" + str(self._palette) + "]"
    
    # getters
    def get_filename(self):
        return self._filename
    
    def get_palette(self):
        return self._palette

    def get_palette_blue_first(self):
        return self._palette_blue_first
    
    def get_palette_red_first(self):
        return self._palette_red_first
    
    # setters
    def set_filename(self, filename):
        self._filename = filename
    
    def set_palette(self, palette):
        self._palette = palette

    def _make_palette_blue_first(self):
#===============================================================================
#        Make a copy of the palette, packing the 32-bit values into 24-bit
#        format.  Some image viewers have issues with TGA files that contain
#        32-bit color palettes.        
#===============================================================================
        self._palette_blue_first = make_palette_blue_first(self._palette)
            
    def _make_palette_red_first(self):
#===============================================================================
#        Returns the requested palette in 24-bit format, with red in the low-order
#        byte.  This is the format used in GIF files.
#===============================================================================
        self._palette_red_first = make_palette_red_first(self._palette)
    
    def load(self):
        '''Takes a 256-entry color palette, with each entry a 3-byte triplet, with
        color values stored in reverse order.  This will expand each 3-byte
        triple into a 32-bit word, fix the color ordering so blue is properly
        stored in the low byte, and pad the alpha channel.'''
        
        # TODO: investigate if this is working
        length = self.ENTRY_NUMBER * self.PALETTE_SIZE
        
        pal_file = open(self._filename, 'rb')
        
        if pal_file:
#===============================================================================
#            Skip the first 8 bytes at the start of the file.  The first four
#            bytes are 0x0000308, which is the size of the file.  The next four
#            bytes are 0x000B123 -- no idea what that value means (may be some
#            kind of version number from the original graphics editor, similar
#            to the values found in Daggerfall palettes).
#===============================================================================
            pal_file.seek(8, os.SEEK_SET)
            
            r = pal_file.read(length)
            pal_file.close()

            fmt = str(length) + 'B'

            raw = struct.unpack(fmt, r)
            
#===============================================================================
#            # if the index is zero, we don't handle the alpha channel
#            self._palette[0] = raw[0] << 16 | raw[1] << 8 | raw[2]
#===============================================================================

            for i in xrange(0, self.PALETTE_SIZE):
                #print chr(raw[i*3]), chr(raw[i*3 +1]), chr(raw[i*3+2])
                #print ':1:',raw[i*3],Utils.Utils.bin(raw[i*3]), Utils.Utils.bin(raw[i*3] << 16)
                #print ':2:',raw[i*3+1],Utils.Utils.bin(raw[i*3+1]), Utils.Utils.bin(raw[i*3+1] <<8)
                #print ':3:',raw[i*3+2],Utils.Utils.bin(raw[i*3+2])
                #              A      r                    g                    b
                #self._palette[i] = raw[i * 3] << 16 | raw[i * 3 + 1] << 8 | raw[i * 3 + 2]
                #print ':4:',bin(self._palette[i])
                #green, red, blue
#===============================================================================
#            For anything other than zero, make sure the alpha channel is
#            non-zero.  Index zero is used to indicate transparent zeroes for
#            many images (at least effects, characters (CFA files), and some
#            geometry (such as keyholes)).
#            
#            Render has been rewritten to work in colormapped space instead
#            of 32-bit ARGB, so the alpha channel does not matter anymore.
#            
#            TODO: render? alpha channel? what is this?!?!
#===============================================================================
                if i > 0:
                    a = 255
                else:
                    a = 0
                r,g,b = raw[i*3],raw[i*3+1], raw[i*3+2]
                self._palette[i] = a,r,g,b
            
        self._make_palette_red_first()
        self._make_palette_blue_first()
        
    def flatten(self):
        ret = []
        
        for (r,g,b) in self._palette:
            ret.extend([r,g,b])
        return ret